package com.example.service.impl;

import com.example.config.RabbitMQConfig;
import com.example.controller.request.AccountLoginRequest;
import com.example.controller.request.AccountRegisterRequest;
import com.example.enums.AuthTypeEnum;
import com.example.enums.BizCodeEnum;
import com.example.enums.EventMessageType;
import com.example.enums.SendCodeEnum;
import com.example.manager.AccountManager;
import com.example.model.AccountDO;
import com.example.mapper.AccountMapper;
import com.example.model.EventMessage;
import com.example.model.LoginUser;
import com.example.service.AccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.service.NotifyService;
import com.example.utils.CommonUtil;
import com.example.utils.IDUtil;
import com.example.utils.JWTUtil;
import com.example.utils.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.params.SetParams;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 二当家小D
 * @since 2022-06-02
 */
@Service
@Slf4j
public class AccountServiceImpl extends ServiceImpl<AccountMapper, AccountDO> implements AccountService {

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private AccountManager accountManager;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RabbitMQConfig rabbitMQConfig;

    /**
     * 免费流量包固定商品ID
     */
    private static final Long FREE_TRAFFIC_PRODUCT_ID = 1l;
    /**
     * 手机验证码验证
     * 密码加密 (TODO)
     * 账户唯一性检查 (TODO)
     * 插入数据库
     * 新注册用户福利发放 (TODO)
     *
     * @param registerRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public JsonData register(AccountRegisterRequest registerRequest) {

        boolean checkCode = false;

        if(StringUtils.isNotBlank(registerRequest.getPhone())){
            checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER,registerRequest.getPhone(),registerRequest.getCode());
        }
        //验证码错误
        if(!checkCode){
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }
        AccountDO accountDO = new AccountDO();
        BeanUtils.copyProperties(registerRequest,accountDO);
        //认证级别
        accountDO.setAuth(AuthTypeEnum.DEFAULT.name());

        //生成唯一账号(雪花算法)
        accountDO.setAccountNo(Long.parseLong(IDUtil.geneSnowFlakeID()+""));

        //设置密码 密匙 盐
        accountDO.setSecret("$1$"+ CommonUtil.getStringNumRandom(8));

        String cryptPwd = Md5Crypt.md5Crypt(registerRequest.getPwd().getBytes(), accountDO.getSecret());
        accountDO.setPwd(cryptPwd);

        int rows = accountManager.insert(accountDO);
        log.info("row:{},注册成功:{}",rows,accountDO);

        //用户注册成功，发放福利
        userRegisterInitTask(accountDO);

        return JsonData.buildSuccess("注册成功!");
    }

    /**
     * 1、根据手机号去找
     * 2、
     * @param loginRequest
     * @return
     */
    @Override
    public JsonData login(AccountLoginRequest loginRequest) {
        List<AccountDO> accountDOList = accountManager.findByPhone(loginRequest.getPhone());
        if(accountDOList!=null && accountDOList.size() == 1){

            AccountDO accountDO = accountDOList.get(0);

            String md5Crypt = Md5Crypt.md5Crypt(loginRequest.getPwd().getBytes(), accountDO.getSecret());
            if(md5Crypt.equalsIgnoreCase(accountDO.getPwd())){
                LoginUser loginUser = LoginUser.builder().build();
                BeanUtils.copyProperties(accountDO,loginUser);
                //生成token
                String token = JWTUtil.geneJsonWebTokne(loginUser);
                return JsonData.buildSuccess(token);
            }else {
                return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }
        }else {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }
    }

    /**
     * 初始化发放福利: 流量包
     * @param accountDO
     */
    private void userRegisterInitTask(AccountDO accountDO) {
        EventMessage eventMessage = EventMessage.builder()
                .messageId(IDUtil.geneSnowFlakeID().toString())
                .accountNo(accountDO.getAccountNo())
                .eventMessageType(EventMessageType.TRAFFIC_FREE_INIT.name())
                .bizId(FREE_TRAFFIC_PRODUCT_ID.toString())
                .build();
        //发放流量包消息
        rabbitTemplate.convertAndSend(rabbitMQConfig.getTrafficEventExchange()
                ,rabbitMQConfig.getTrafficFreeInitRoutingKey(),eventMessage);
    }
}
